#include "IDevice.h"

#include <QTimer>

#include "ModbusHelper.h"
#include "ModbusManager.h"
#include "common/define.h"

IDevice::IDevice(const QString& deviceName, QObject* parent)
    : QObject(parent), m_deviceName(deviceName), m_deviceDataTimer(nullptr)
{
    m_deviceAttribute = DEVICE_MAP.value(m_deviceName);
    // 初始化定时器
    m_deviceDataTimer = new QTimer(this);
    connect(m_deviceDataTimer, &QTimer::timeout, this, [this]() {
        if (isEnabled()) {
            onGetDeviceData();
        }
    });
    m_deviceDataTimer->setInterval(3000);

    // 连接ModbusManager信号
    connect(ModbusManager::instance(), &ModbusManager::deviceError, this,
            [this](const QString& deviceId, const QString& errorMessage) {
                if (deviceId == m_deviceName) {
                    emit commStatusChanged(false);
                }
            });

    connect(ModbusManager::instance(), &ModbusManager::deviceCommSuccess, this,
            [this](const QString& deviceId) {
                if (deviceId == m_deviceName) {
                    emit commStatusChanged(true);
                }
            });
}

bool IDevice::isEnabled() { return ModbusManager::instance()->isDeviceEnabled(m_deviceName); }

void IDevice::startDataMonitoring()
{
    if (isEnabled()) {
        onGetDeviceData();
    }
    if (m_deviceDataTimer && !m_deviceDataTimer->isActive()) {
        qDebug() << m_deviceName << ":startDataMonitoring";
        m_deviceDataTimer->start();
    }
}

void IDevice::stopDataMonitoring()
{
    if (m_deviceDataTimer && m_deviceDataTimer->isActive() && isIdle()) {
        qDebug() << m_deviceName << ":stopDataMonitoring";
        m_deviceDataTimer->stop();
    }
}

void IDevice::control(quint16 addr, quint16 data)
{
    if (DEVICE_MAP[m_deviceName].isOperable == false) {
        return;
    }
    if (m_busyFlags.controlBusy) {
        return;
    }
    m_busyFlags.controlBusy = true;
    ModbusHelper* modbus = ModbusManager::instance()->getModbusHelper(m_deviceName);
    if (!modbus) {
        qDebug() << "Failed to get ModbusHelper for device:" << m_deviceName;
        m_busyFlags.controlBusy = false;
        return;
    }
    QVector<quint16> _data;
    _data << data;
    modbus->asyncWrite(addr, _data)
        .fail([this](const QString& error) {
            qDebug() << "Failed to write register for device:" << m_deviceName << "Error:" << error;
        })
        .finally([this]() { m_busyFlags.controlBusy = false; });
}